python中的模块与包的导入 您所在的位置:网站首页 python 绝对引用 python中的模块与包的导入

python中的模块与包的导入

2024-01-20 16:26| 来源: 网络整理| 查看: 265

概述

文件-->块 :模块导入

模块通常对应于文件,而python会建立模块对象,以包含模块文件内所赋值的所有变量名。

简而言之,模块就是命名空间(变量名建立所在的场所),而存在于模块之内的变量名就是模块对象的属性

目录-->包 :包导入

事实上,包导入是把计算机上的目录变成另一个Python命名空间,而属性则对应目录中所包含的子目录和模块文件。

模块 模块导入操作

必须通过模块名称得到该模块的属性:

import module

直接在脚本中使用复制后的对象名,而不需要通过模块, 这里的object可是变量、函数或类:

from module import object

把模块中所有变量名复制到进行导入的作用域内:

from module import *

import语句和from语句的as扩展:

import module as md from module import object as obj

import与from语句的异同

import和from是赋值语句:

import将整个模块对象赋值给一个变量名 模块对象赋值

from将一个或多个变量名赋值给另一个模块中同名的对象 变量名赋值

模块导入常用实例:导入当前目录下的另一个文件

方法一:

from folder_name.other_file import *

方法二:

在PyCharm2017中同目录下import其他模块,会出现No model named ...的报错,但实际可以运行

这是因为PyCharm不会将当前文件目录自动加入source_path。

在当前目录右键make_directory as-->Sources Root

python导入模块

同一目录下在a.py中导入b.py

import b 或者 from bimport 方法/函数

不同目录下在a.py中导入b.py

import sys

sys.path.append('b模块的绝对路径')

import b

包 __init__.py文件

如果选择包导入,就必须多遵循一条约束:包导入语句的路径中的每个目录内都必须有__init__.py这个文件,否则导入包会失败。

__init__.py文件的作用是将文件夹变为一个Python模块,Python中的每个模块的包中,都有__init__.py文件

__init__.py文件的作用:

包初始化的钩子

替目录产生模块命名空间

使用目录导入时实现from *行为的角色

空的

__init__.py可以包含Python程序代码,就像普通模块文件,也可以完全是空的。

批量导入

在导入一个包时,实际上导入了它的__init__.py文件

可以在__init__.py文件中批量导入我们所需要的模块,而不再需要一个一个的导入

# package

# __init__.py import re import urllib import sys import os

# a.py

import package print(package.re, package.urllib,package.sys, package.os)

模块全部导

以*导入时,package内的module是受__init__.py限制的

__init__.py 中还有一个重要的变量,叫做 __all__。我们有时会使出一招“全部导入”,也就是这样:

from PackageNameimport *

这时 import 就会把注册在包__init__.py 文件中 __all__ 列表中的子模块和子包导入到当前作用域中来

# __init__.py

__all__ = ['os', 'sys', 're', 'urllib']

# a.py

from package import *

扩展包的搜索路径

__init__.py的__path__变量指定了包的搜索路径

变量__path__, 默认情况下只有一个元素,就是当前包的路径,修改__path__,可以修改此包内的搜索路径

import与from语法

模块导入语法中导入文件名的地方改为列出路径的名称,彼此以点号间隔

包的相对导入

包相对导入:位于同一包中的模块(位于与语句中给出的文件相同包路径中)

包绝对导入:模块导入搜索路径上某处的模块

从查到的资料来看,关于import路径的来说,分成3类:

absolute import

import xml

importyoupackage.xml

from youpackageimport xml

这几种都算绝对路径

relative import

import xml

从这个语句上是看不出来import的是标准库的xml,还是你的包里的一个库叫xml。

explicit relative import

from . import xml

from .xml importsome_thing

from ..xml importsome_thing

这些以点开头的import明确的表示了import的是相对路径,从而避免了普通relative import的麻烦。

Attempted relative import in non-package

The Python importmechanism works relative to the __name__ of the current file. When you executea file directly, it doesn't have its usual name, but has "__main__"as its name instead. So relative imports don't work.

顶层的module运行时,不能用相对导入,即使顶层有init文件也不行。

You can execute it using the -m option. Ifyou have a part of your package that is meant to be run as a script, you canalso use the __package__ attribute to tell that file what name it's supposed tohave in the package hierarchy.

When the main moduleis specified by its filename, then the __package__ attribute will be set toNone. To allow relative imports when the module is executed directly,boilerplate similar to the following would be needed before the first relativeimport statement:

if __name__ =="__main__" and __package__ is None:

__package__ ="expected.package.name"

Note that thisboilerplate is sufficient only if the top level package is already accessiblevia sys.path. Additional code that manipulates sys.path would be needed inorder for direct execution to work without the top level package already being importable.

包含相对路径import 的python脚本不能直接运行,只能作为module被引用。原因正如手册中描述的,所谓相对路径其实就是相对于当前module的路径,但如果直接执行脚本,这个module的name就是“__main__”, 而不是module原来的name, 这样相对路径也就不是原来的相对路径了,导入就会失败,出现错误“ValueError: Attempted relative import innon-package”

Relative imports use a module's __name__attribute to determine that module's position in the package hierarchy. If themodule's name does not contain any package information (e.g. it is set to '__main__')then relative imports are resolved as if the module were a top level module,regardless of where the module is actually located on the file system.

Note that both explicit and implicit relativeimports are based on the name of the current module. Since the name of the mainmodule is always "__main__" , modules intended for use as the main moduleof a Python application should always use absolute imports.

虽然PEP338搞定了explicit relative import 在-m执行时的问题,但是搞不定直接文件执行的情况。所以用来做程序入口的模块必须使用绝对引用

sys.path 和sys.modules:

sys.path包含了module的查找路径;

sys.modules包含了当前所load的所有的modules的dict(其中包含了builtin的modules)

显式相对导入和隐式相对导入

Python相对导入与绝对导入,这两个概念是相对于包内导入而言的。包内导入即是包内的模块导入包内部的模块。

模块搜索路径

sys.path是python的搜索模块的路径集,是一个list

sys.path.append(‘你的模块的名称’)

添加相关的路径,但在退出python环境后自己添加的路径就会自动消失!

当你要导入的文件或者目录不和你的当前文件同目录时,你需要跳到这个你要导入文件的父级目录,然后一级一级的用点号连接走过的目录或者文件,然后就可以了;至于要怎么跳到这个父级目录,比较通用的就是,将父级目录加入系统路径,然后用点号一级一级的寻找,直到到达你要导入的模块。

文件相对路径 root_path = os.path.dirname(__file__)

主要是当前工作目录根据运行的脚本不同而不同,即当前目录变来变去

某个被使用的外部文件,对一个文件来说的相对路径,对另一个文件的相对路径却不同

或者

os.chdir(‘文件路径’) print(os.getcwd()) 文件相对路径与包导入相对路径是两码事

import sys

sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))

os.path.abspath(__file__)

import os import sys from pathlib importPath sys.path.append((Path(os.path.abspath(__file__)).parents[3]).as_posix()) print("sys.path.append:", (Path(os.path.abspath(__file__)).parents[3]).as_posix())

pycharm导入

pycharm默认的根目录是工程目录,而在linux中python xxx.py执行时默认的根目录是xxx.py所在的目录,可以做如下的改变:

import os import sys from pathlib importPath sys.path.append((Path(os.path.abspath(__file__)).parents[3]).as_posix()) print("sys.path.append:", (Path(os.path.abspath(__file__)).parents[3]).as_posix())

或者在根目录 以python ./根目录/xxx.py来执行

python中模块常用预定义的内置变量名变量

'__builtins__'

'__doc__'

'__file__'

'__name__'

'__package__'

导入总结



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有